//
//  CameraView.m
//  iPhone SRV
//
//  Created by Nick Kitchener on 06/07/2009.
//  Copyright 2009 Nick Kitchener. All rights reserved.
//

// The fun here is that we don't copy the image data out of the initial buffer deep in the JPG operation for performance.
// This means the JPG has to remain until the system requests a drawRect.
// Additional issue is that the IO thread will operate independently on the object.

#import "CameraView.h"
#import "SRVGetJPGFrameOperation.h"


@implementation CameraView
@synthesize blackfin;

- (id)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
		displayedJPGOperation = nil;
		displayedImageData = nil;
		displayedImage = [UIImage imageWithContentsOfFile:@"robot.jpg"];
		inprogressJPGOperation = nil;
		switchImage = NO;
    }
    return self;
}

- (void)dealloc {
	
	if( displayedJPGOperation != nil )
		[displayedJPGOperation release]; // we leave the operation to clear it's own internal stuff
	if( inprogressJPGOperation != nil )
		[inprogressJPGOperation release]; // release the in progress.
	[super dealloc];
}


-(void)viewWillAppear {
	idle = YES;
	// as we're about to appear we'll set up the RunLoopTimer so we have a video stream effect.
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.1
													  target:self selector:@selector(timerFireMethod:)
													userInfo:nil repeats:YES];
    repeatingTimer = timer;		
}

- (void)viewWillDisappear {
	// stop the timer as we're not in view.
	[repeatingTimer invalidate];
	repeatingTimer = nil;
}

- (void)timerFireMethod:(NSTimer*)theTimer {
	if(idle) {
		idle = NO;
		[self initiateNewImageOperation];
	}
}

-(void) drawRect: (CGRect) rect {
	SRVGetJPGFrameOperation *toBeReleased = nil;
	NSData					*toBeReleasedData = nil;
	UIImage					*toBeReleasedImage = nil;
	
	if( switchImage ) {
		toBeReleased = displayedJPGOperation;
		toBeReleasedData = displayedImageData;
		toBeReleasedImage = displayedImage;
		
		displayedJPGOperation = inprogressJPGOperation;
		displayedImageData    = [displayedJPGOperation data]; // create (alloc)
		displayedImage		  = [UIImage imageWithData:displayedImageData]; // create (alloc) a non-cached data image to the jpg.
		
		inprogressJPGOperation = nil;
		
		switchImage = NO;
	}
	
	[displayedImage drawInRect:rect];
	
//	if(toBeReleasedImage!=nil)
//		[toBeReleasedImage release];
//	if(toBeReleasedData!=nil)
//		[toBeReleasedData release];
	if(toBeReleased!=nil) {
//		NSLog(@"tbr retain count = %d", [toBeReleased retainCount]);
		[toBeReleased release];
	}
	
	idle = YES;
}

-(void)initiateNewImageOperation {
	inprogressJPGOperation = [[SRVGetJPGFrameOperation alloc] init];
	[inprogressJPGOperation setCompletionListener:self];
	[blackfin setOperation:inprogressJPGOperation];
}

-(void)switchDisplayedImage {
	// the data has to survive whilst it's being displayed.
	switchImage = YES;
	[self setNeedsDisplay];
}

// JPG operation completed
-(void)operationCompleted:(SRVOperation *)operation {
	if( operation == inprogressJPGOperation )
		[self switchDisplayedImage]; 		// set up image swap
}

-(void)operationFailed:(SRVOperation *)operation {
	if( operation == inprogressJPGOperation ) {
		NSLog(@"Operation failed %@", operation);
		[inprogressJPGOperation release];
		inprogressJPGOperation = nil;
		idle = YES;
	}
}

@end
